<template>
  <div>
    <zz-tree
      :treeData="companyList"
      :options="options"
      :showCheckbox="showCheckbox"
      :isPaddingLeft = isPaddingLeft
      @node-select="selectDepart"
      @node-arrow="arrowDepartClick"
      @node-click="itemClick"
    ></zz-tree>
  </div>
</template>

<script>
  import label from './label.js'
  import { mapGetters } from 'vuex'
  export default {
    name: 'zz-depart',
    mixins: [label],
    data () {
      return {
        companyList: [
          {
            label: '全公司',
            id: -1,
            open: true,
            checked: true,
            isCompany: true,
            children: []
          }
        ],
        DpTree: [],
        isDepartLabel: true,
        departCodes: [],
        selected: {
          isCompany: true
        },
        options: {
          halfCheckedStatus: false // 控制父框是否需要半钩状态
        },
        friendFletter: ''
      }
    },
    computed: {
      ...mapGetters({
        employees: 'getEmployees', // 员工列表
        currentUser: 'currentUser',
        chooseDepart: 'getChooseDepart',
        chooseEmployees: 'getChooseEmployees'
      })
    },
    props: {
      type: {
        type: '',
        default: 'retrieve'
      },
      // 是否从外部获取部门列表
      isDepartProps: {
        type: Boolean,
        default: false
      },
      departListProps: {
        type: Array,
        default: function () {
          return []
        }
      },
      isHandle: {
        type: Boolean,
        default: false
      },
      // 是否开启选择员工
      isGetEmployees: {
        type: Boolean,
        default: true
      },
      isChooseMember: {
        type: Boolean,
        default: true
      },
      // 是否显示选择框
      showCheckbox: {
        type: Boolean,
        default: false
      },
      // 默认打钩的部门
      checkList: {
        type: Array,
        default: function () {
          return []
        }
      },
      // 是否开启选择部门
      isChooseDepart: {
        type: Boolean,
        default: false
      },
      openEmployees: {
        type: Boolean,
        default: true
      },
      // 是否开启选择全公司
      isChooseCompany: {
        type: Boolean,
        default: false
      },
      // 是否显示未分配部门
      isUndistributed: {
        type: Boolean,
        default: false
      },
      // 是否开启过滤
      isFilter: {
        type: Boolean,
        default: false
      },
      // 是否管理员
      admin: {
        type: Boolean,
        default: false
      },
      // 员工状态
      status: {
        type: Number,
        default: 1
      },
      // 是否加入我的朋友
      isFriend: {
        type: Boolean,
        default: false
      },
      // 是否加入我的标签
      isLabel: {
        type: Boolean,
        default: false
      },
      textCompanyArr: {
        type: String,
        default: ''
      },
      textDepartArr: {
        type: String,
        default: ''
      },
      isGetEmployee: {
        type: Boolean,
        default: false
      },
      // 是否增加左边内边距
      isPaddingLeft: {
        type: Boolean,
        default: false
      },
      // 过滤条件
      filterRule: [String, Number, Array]
    },
    watch: {
      departListProps (departs) {
        // 设置部门管理员下的员工和人数
        const items = departs.slice(0)
        this.departCodes = items.map((x) => { return x.code })
        this.setDepartments(items)
        this.$store.dispatch({
          type: 'searchEmployee',
          codes: this.departCodes
        })
        this.$store.commit('updateEmployeesCount', {codes: this.departCodes, isCompany: true})
      },
      chooseDepart () {
        if (!this.isDepartProps) {
          this.updateDepartmentsThrottle()
        } else {
          this.$emit('queryDepart')
        }
      },
      chooseEmployees () {
        this.getEmployee()
      }
    },
    created () {
      this.$set(this.options, 'showCheckbox', this.showCheckbox)
      this.$set(this.options, 'noParentChecked', true)
      this.$set(this.options, 'multiple', true)
      if (this.showCheckbox) {
        for (let item of this.companyList) {
          if (item.isCompany) {
            item.checked = false
            break
          }
        }
      }
    },
    mounted () {
      this.getCompany()
      // 是否开启我的标签
      if (this.isLabel) {
        this.companyList.unshift({
          label: '我的标签',
          id: -3,
          open: false,
          checked: false,
          isLabel: true,
          children: []
        })
        this.findLabel()
      }
      // 是否开启我的盆友
      if (this.isFriend) {
        this.companyList.unshift({
          label: '我的朋友',
          id: -2,
          fletter: '',
          open: false,
          checked: false,
          isFriend: true,
          children: []
        })
        this.setFriendFletter()
      }
      this.updateDepartmentsThrottle = this.$Throttle(this.updateDepartments, 1000)
    },
    methods: {
      // 获取公司列表
      getCompany () {
        // 是否跨公司选择
        if (this.isAllowCompany) {
          this.getCompanyList()
        } else {
          this.getDepartmentsIndexDB()
          // 是否直接获取员工
          if (this.isGetEmployees && !this.isFilter && !this.isDepartProps) {
            this.$store.dispatch({
              type: 'searchEmployee'
            })
          }
        }
      },

      // 获取公司列表
      getCompanyList () {
        this.$axios({
          method: 'post',
          url: '/front/retrieve/findallowncompany.htm'
        }).then(res => {
          if (res.data.errorMsg) {
            this.$message.error(res.data.errorMsg)
          } else {
            this.setCompanyList(res.data.result)
          }
        }, err => {
          this.$message.error(err)
        })
      },

      setCompanyList (companys) {
        this.companyList = companys.map((company) => {
          if (this.currentUser.coId === company.coId) {
            this.$set(company, 'open', true)
          } else {
            this.$set(company, 'open', false)
          }
          Object.assign(company, {label: company.coName})
          Object.assign(company, {isCompany: true})
          Object.assign(company, {children: []})
          return company
        })
        this.getDepartmentsIndexDB()
        this.getEmployee()
      },

      // 获取部门
      getDepartmentsIndexDB () {
        // 是否从服务端获取
        if (this.isDepartProps) {
          const items = this.departListProps.slice(0).map((item) => {
            delete item.child
            return item
          })
          this.departCodes = items.map((x) => { return x.code })
          this.setDepartments(items)
        } else {
          this.$DesignDB.findDepartments(this.currentUser.coId, (departments) => {
            this.setDepartments(departments)
          })
        }
      },
      // 更新部门
      updateDepartments () {
        for (let item of this.companyList) {
          if (item.isCompany) {
            item.children = []
            break
          }
        }
        this.getDepartmentsIndexDB()
      },

      // 部门分级
      setDepartments (departments) {
        function repeatTimes (code) {
          let times = 0
          Array.from(code).forEach(c => {
            if (c === '|') {
              times++
            }
          })
          return times
        }
        function sortDep (a, b) {
          let aTimes = repeatTimes(a.code)
          let bTimes = repeatTimes(b.code)
          let result = aTimes - bTimes
          if (result === 0) {
            return a.orderNum - b.orderNum
          } else {
            return result
          }
        }
        let dps = departments.sort(sortDep)
        let map = new Map()
        let dpTree = dps.filter(d => {
          map.set(d.departmentId, d)
          return !d.parentId
        })
        dps.forEach(d => {
          if (d.parentId) {
            let parent = map.get(d.parentId)
            if (parent) {
              if (!parent.child) {
                parent.child = []
              }
              parent.child.push(d)
            } else {
              dpTree.push(d)
            }
          }
        })
        this.muDpTree(dpTree)
      },

      muDpTree (dpTree) {
        let DataEach = (items, data) => {
          data.forEach(x => {
            let checked = false
            if (this.checkList.includes(x.departmentId)) {
              checked = true
            }
            let obj = {
              id: x.departmentId,
              coId: x.coId,
              code: x.code,
              label: x.departmentName,
              nodeSelectNotAll: false,
              openArr: this.isChooseDepart,
              textArr: this.textDepartArr,
              isDepart: true,
              showArr: false,
              open: false,
              checked: checked,
              parentId: x.parentId
            }
            // 是否加入操作
            if (this.isHandle) {
              this.$set(obj, 'showSelect', false)
              if (this.currentUser.superAdmin || this.currentUser.advancedAdmin) {
                this.$set(obj, 'select', {1: '新增', 2: '重命名', 3: '删除', 4: '上移', 5: '下移'})
              } else {
                this.$set(obj, 'select', {2: '重命名'})
              }
            }
            if (x.child) {
              this.$set(obj, 'children', [])
              DataEach(obj.children, x.child)
              this.pushDepart(items, obj)
            } else {
              // 是否在部门下 加载员工
              if (this.isGetEmployee) {
                this.pushEmployee(items, obj)
              } else {
                this.pushDepart(items, obj)
              }
            }
          })
        }
        this.DpTree = []
        DataEach(this.DpTree, dpTree)
        this.setDpTree(this.DpTree)
      },

      // 设置部门
      setDpTree (items) {
        // 是否加入操作
        for (let item of this.companyList) {
          if (item.isCompany) {
            if (this.isHandle) {
              this.$set(item, 'showSelect', false)
              if (this.currentUser.superAdmin || this.currentUser.advancedAdmin) {
                this.$set(item, 'select', {1: '新增'})
              }
            }
            // 是否显示选择全公司
            if (this.isChooseCompany) {
              this.$set(item, 'openArr', true)
              this.$set(item, 'showArr', false)
              this.$set(item, 'textArr', this.textCompanyArr)
            }
            this.$set(item, 'children', items)
            // 是否显示未分配部门
            if (this.isUndistributed) {
              item.children.push({
                label: '未分配部门',
                checked: false,
                undistributed: true
              })
            }
            break
          }
        }
      },

      pushDepart (items, obj) {
        // 是否开启过滤
        if (this.isFilter) {
          if (Array.isArray(this.filterRule)) {
            if (this.filterRule.includes(obj.id)) {
              this.pushFilterDepart(items, obj)
            }
          } else {
            if (this.filterRule === obj.id) {
              this.pushFilterDepart(items, obj)
              this.selected = obj
              this.getEmployee()
            }
          }
        } else {
          items.push(obj)
        }
      },

      pushFilterDepart (items, obj) {
        obj.checked = true
        for (let item of this.companyList) {
          if (item.isCompany) {
            item.checked = false
            break
          }
        }
        this.selected = obj
        if (this.isGetEmployee) {
          this.getEmployee()
        }
        items.push(obj)
      },

      pushEmployee (items, obj) {
        this.$DesignDB.findEmployees(obj.coId, obj, (employees) => {
          let list = employees.map((x) => {
            this.$set(x, 'isEmployee', true)
            this.$set(x, 'label', x.mName)
            return x
          })
          this.$set(obj, 'children', list)
          items.push(obj)
        })
      },

      // 设置我的朋友索引
      setFriendFletter () {
        for (let item of this.companyList) {
          if (item.isFriend) {
            item.children.push({
              label: '@',
              fletter: '',
              checked: false,
              isFriend: true
            })
            for (let i = 0; i < 26; i++) {
              let fletter = String.fromCharCode(65 + i)
              item.children.push({
                label: fletter,
                fletter: fletter,
                isFriend: true,
                checked: false
              })
            }
            break
          }
        }
      },

      // 点击我的朋友
      findFriend () {
        const form = {
          'query.friendFletter': this.friendFletter,
          'query.schType': 1,
          'query.pageSize': 1000,
          'query.currentPage': 1
        }
        this.$axios({
          method: 'post',
          url: `${this.$site.oaServer}/front/retrieve/friendcontact.htm`,
          data: this.$qs.stringify(form, {indices: false})
        }).then(res => {
          if (res.data.errorMsg) {
            this.$message.error(res.data.errorMsg)
          } else {
            this.$emit('clickDepart', {isFriend: true, label: '我的朋友', list: res.data.list})
          }
        })
      },

      // 获取我的标签
      setLabel () {
        for (let item of this.companyList) {
          if (item.isLabel) {
            item.children = [...this.labelList, ...item.children]
            break
          }
        }
      },

      // 设置我的标签下的员工
      setLabelConcat () {
        this.$emit('clickDepart', {...this.selected, ...{list: this.labelContact}})
      },

      // 点击回调事件
      itemClick (node) {
        this.selected = node
        // 是否获取我的朋友
        if (this.isFriend && node.isFriend) {
          this.friendFletter = node.fletter
          this.findFriend()
          return
        }
        // 是否获取我的标签
        if (this.isLabel && node.isLabel) {
          this.labelcontact(node.lid)
          return
        }
        // 是否直接选中部门
        if (this.openEmployees) {
          // 是否获取员工
          if (this.isGetEmployees) {
            this.getEmployee()
          }
          this.$emit('clickDepart', node)
        } else {
          this.arrowDepartClick(node)
        }
        // 是否获取员工
        if (this.isGetEmployees) {
          this.getEmployee()
        }
        // 是否直接点击员工
        if (node.isEmployee) {
          this.$emit('clickEmployee', node)
        } else {
          this.$emit('clickDepart', node)
        }
      },

      // 获取员工
      getEmployee () {
        this.$store.dispatch({
          type: 'searchEmployee',
          admin: this.admin,
          status: this.status,
          code: this.selected.code,
          codes: this.departCodes,
          undistributed: this.selected.undistributed
        }).then(() => {
          if (this.selected.isCompany) {
            Object.assign(this.selected, {'codes': this.departCodes})
            Object.assign(this.selected, {'advancedAdmin': this.currentUser.advancedAdmin})
          }
          this.$store.commit('updateEmployeesCount', this.selected)
        })
      },

      // 点击箭头事件
      arrowDepartClick (node) {
        if (node.isCompany) {
          this.$emit('companyHandle', node)
        } else {
          this.$emit('departHandle', node)
        }
      },

      selectDepart (data) {
        this.$emit('selectDepart', data)
      },

      // 刷新
      refreshMemberList (members) {
        let choosed = this.findChooseMids(this.memberList)
        members.forEach(m => {
          m.mName = m.mname
          m.choose = this.isChoose(m.mid, choosed)
        })
        this.memberList = members
      },

      findChooseMids (mans) {
        let chooseMids = []
        mans.forEach(m => {
          if (m.choose) {
            chooseMids.push(m.mid)
          }
        })
        return chooseMids
      },

      isChoose (id, choosedMids) {
        if (!choosedMids || choosedMids.length <= 0) {
          return false
        }
        let choose = false
        choosedMids.forEach(mid => {
          if (mid === id) {
            choose = true
          }
        })
        return choose
      }
    }
  }
</script>
